OpenRoads Designer CONNECT Edition SDK Help

Terrain reporter

Description

  • This is a custom tool for creating data related to terrain elevation.

  • StationOffsetElevation() method creates data for terrain elevation using alignments and given offset. To use this tool the dgn should have active terrain and alignment.

  • DrapeLineAtInterval() Method reads alignments and creates data of draped cross-section lines at given offsets and intervals.

  • To use this tool the dgn should have active terrain, alignment, and profile.

Remarks

  • This sample code is a part of ManagedSDKExample which you get with SDK installation under "examples" section in SDK installation directory.

  • This code is simplified and does not include report generation code, but user can get it under ManagedSDKExample ->Examples ->TerrainReporter.

Source Code




//Required References
using System;
using System.Collections.Generic;
using System.Text;
using Bentley.DgnPlatformNET;
using Bentley.CifNET.GeometryModel.SDK;
using Bentley.CifNET.SDK;
using Bentley.CifNET.LinearGeometry;
using Bentley.CifNET.Formatting;

namespace ManagedSDKExample.Examples
{
    class TerrainReporter
    {
        internal static DgnModel m_activeModel = Bentley.MstnPlatformNET.Session.Instance.GetActiveDgnModel();
        internal static double m_defaultUnitsToMeters = FormatSettingsConstants.GetMasterUnitsToMeters();

        /*------------------------------------------------------------------------------------**/
        /* Reads alignments and creates data of terrain elevations at an interval for report generation.
        /*--------------+---------------+---------------+---------------+---------------+------*/
        internal void StationOffsetElevation()
        {
            List<string> labels = new List<string>() { "STATION", "OFFSET", "NORTHING", "EASTING", "TERRAIN ELEVATION" };
            SortedDictionary<double, string> data = new SortedDictionary<double, string>();
            double interval = ConvertMasterToMeter(100.0);
            double offset = ConvertMasterToMeter(50.0);
            StringBuilder sb = new StringBuilder();

            ConsensusConnection sdkCon = Bentley.CifNET.SDK.Edit.ConsensusConnectionEdit.GetActive();
            if (sdkCon == null)
                return;

            GeometricModel geomModel = sdkCon.GetActiveGeometricModel();
            if (geomModel == null)
                return;

            SurfaceEntity activeSurface = geomModel.ActiveSurface;

            Dictionary<string, string> header = new Dictionary<string, string>();
            header.Add("File Name", geomModel.DgnModel.GetDgnFile().GetFileName());
            header.Add("Model Name", geomModel.DgnModel.ModelName);
            string surfaceName = "No Active Terrain";
            if (activeSurface != null)
            {
                surfaceName = string.IsNullOrEmpty(activeSurface.Name) ? "Unnamed" : activeSurface.Name;
            }
            header.Add("Active Terrain Name", surfaceName);
            header.Add("Interval", "100");
            header.Add("Offset", "50");

            StationFormatSettings settings = StationFormatSettings.GetStationFormatSettingsForModel(Bentley.MstnPlatformNET.Session.Instance.GetActiveDgnModelRef() as DgnModel);
            foreach (Alignment al in geomModel.Alignments)
            {
                if (!al.IsFinalElement)
                {
                    continue;
                }

                StationingFormatter formatter = new StationingFormatter(al);
                Profile activeProfile = al.ActiveProfile;

                data.Clear();
                sb.Clear();

                sb.Append("Horizontal Alignment: ");
                sb.Append(string.IsNullOrEmpty(al.Name) ? "Unnamed" : al.Name);

                sb.Append("Active Vertical Alignment Name: ");
                if (activeProfile != null)
                {
                    sb.Append(string.IsNullOrEmpty(activeProfile.Name) ? "Unnamed" : activeProfile.Name);
                }
                else
                {
                    sb.Append("No Active Vertical Alignment");
                }

                for (double station = 0.0; station < al.LinearGeometry.Length; station += interval)
                {
                    if (!data.ContainsKey(station))
                    {
                        LinearPoint point = al.LinearGeometry.GetPointAtDistanceOffset(station, offset);

                        string stationValue = "";
                        formatter.FormatStation(ref stationValue, station, settings);
                        string offsetValue = FormatNumber(ConvertMeterToMaster(offset));
                        string northingValue = FormatNumber(ConvertMeterToMaster(point.Coordinates.Y));
                        string eastingValue = FormatNumber(ConvertMeterToMaster(point.Coordinates.X));
                        string elevationValue = "No Terrain";
                        if (activeSurface != null)
                        {
                            if (activeSurface is TerrainSurface)
                            {
                                TerrainSurface surface = activeSurface as TerrainSurface;
                                Bentley.TerrainModelNET.DTMDrapedPoint drapedPoint = surface.DTM?.DrapePoint(point.Coordinates);
                                if (drapedPoint != null)
                                {
                                    if (drapedPoint.Code == Bentley.TerrainModelNET.DTMDrapedPointCode.PointOrSide ||
                                        drapedPoint.Code == Bentley.TerrainModelNET.DTMDrapedPointCode.Triangle)
                                    {
                                        elevationValue = FormatNumber(ConvertMeterToMaster(drapedPoint.Coordinates.Z));
                                    }
                                    else if (drapedPoint.Code == Bentley.TerrainModelNET.DTMDrapedPointCode.Void)
                                    {
                                        elevationValue = "In void";
                                    }
                                    else
                                    {
                                        elevationValue = "Outside terrain";
                                    }
                                }
                            }
                        }

                        data.Add(station, string.Format("{0}|{1}|{2}|{3}|{4}", stationValue, offsetValue, northingValue, eastingValue, elevationValue));
                    }
                }
            }
        }

        /*------------------------------------------------------------------------------------**/
        /* Reads alignments and creates data of draped cross-section lines at given offsets and intervals.
        /*--------------+---------------+---------------+---------------+---------------+------*/
        internal void DrapeLineAtInterval()
        {
            ConsensusConnection sdkCon = Bentley.CifNET.SDK.Edit.ConsensusConnectionEdit.GetActive();
            if (sdkCon == null)
                return;

            GeometricModel geomModel = sdkCon.GetActiveGeometricModel();
            if (geomModel == null)
                return;

            SurfaceEntity activeSurface = geomModel.ActiveSurface;

            Dictionary<string, string> header = new Dictionary<string, string>();
            header.Add("File Name", geomModel.DgnModel.GetDgnFile().GetFileName());
            header.Add("Model Name", geomModel.DgnModel.ModelName);
            string surfaceName = "No Active Terrain";
            if (activeSurface != null)
            {
                surfaceName = string.IsNullOrEmpty(activeSurface.Name) ? "Unnamed" : activeSurface.Name;
            }
            header.Add("Active Terrain Name", surfaceName);
            header.Add("Interval", "100");
            header.Add("Left Offset", "50");
            header.Add("Right Offset", "50");

            StringBuilder sb = new StringBuilder();

            StationFormatSettings settings = StationFormatSettings.GetStationFormatSettingsForModel(Bentley.MstnPlatformNET.Session.Instance.GetActiveDgnModelRef() as DgnModel);
            foreach (Alignment al in geomModel.Alignments)
            {
                if (!al.IsFinalElement)
                {
                    continue;
                }

                StationingFormatter formatter = new StationingFormatter(al);
                Profile activeProfile = al.ActiveProfile;

                sb.Clear();

                sb.Append("Horizontal Alignment: ");
                sb.Append(string.IsNullOrEmpty(al.Name) ? "Unnamed" : al.Name);

                sb.Append("Active Vertical Alignment Name: ");
                if (activeProfile != null)
                {
                    sb.Append(string.IsNullOrEmpty(activeProfile.Name) ? "Unnamed" : activeProfile.Name);
                }
                else
                {
                    sb.Append("No Active Vertical Alignment");
                }

                double interval = ConvertMasterToMeter(100.0);
                double offset = ConvertMasterToMeter(50.0);
                Dictionary<string, string> data = new Dictionary<string, string>();
                for (double station = 0.0; station < al.LinearGeometry.Length; station += interval)
                {
                    data.Clear();

                    LinearPoint pointOnAlignment = al.LinearGeometry.GetPointAtDistanceOffset(station, 0.0);
                    LinearPoint point1 = al.LinearGeometry.GetPointAtDistanceOffset(station, -offset);
                    LinearPoint point2 = al.LinearGeometry.GetPointAtDistanceOffset(station, offset);

                    string stationValue = "";
                    formatter.FormatStation(ref stationValue, station, settings);
                    data["Station"] = stationValue + "|";
                    data["Offset"] = "|";
                    data["Elevation"] = "|";
                    data["Easting (X)"] = "|";
                    data["Northing (Y)"] = "|";

                    if (activeSurface != null)
                    {
                        if (activeSurface is TerrainSurface)
                        {
                            TerrainSurface surface = activeSurface as TerrainSurface;
                            Bentley.TerrainModelNET.DTMDrapedLinearElement linearElement = surface.DTM?.DrapeLinearPoints(new List<Bentley.GeometryNET.DPoint3d>() { point1.Coordinates, point2.Coordinates });
                            if (linearElement != null)
                            {
                                foreach (var pt in linearElement)
                                {
                                    string typeValue = "";
                                    switch (pt.Code)
                                    {
                                        case Bentley.TerrainModelNET.DTMDrapedLinearElementPointCode.External:
                                            typeValue = "<font color=\"ff0000\"><em>External</em></font>";
                                            break;
                                        case Bentley.TerrainModelNET.DTMDrapedLinearElementPointCode.Void:
                                            typeValue = "<font color=\"ff0000\"><em>Void</em></font>";
                                            break;
                                        default:
                                            break;
                                    }

                                    Bentley.GeometryNET.DVector3d vector = Bentley.GeometryNET.DPoint3d.Subtract(pointOnAlignment.Coordinates, pt.Coordinates);
                                    double pointOffset = vector.MagnitudeXY * Math.Sign(vector.AngleXY.Degrees);
                                    string offsetValue = FormatNumber(ConvertMeterToMaster(pointOffset));
                                    string elevationValue = (string.IsNullOrEmpty(typeValue)) ? FormatNumber(ConvertMeterToMaster(pt.Coordinates.Z)) : "";
                                    string eastingValue = FormatNumber(ConvertMeterToMaster(pt.Coordinates.X));
                                    string northingValue = FormatNumber(ConvertMeterToMaster(pt.Coordinates.Y));

                                    data["Station"] += typeValue + "|";
                                    data["Offset"] += offsetValue + "|";
                                    data["Elevation"] += elevationValue + "|";
                                    data["Easting (X)"] += eastingValue + "|";
                                    data["Northing (Y)"] += northingValue + "|";
                                }
                            }
                        }
                    }
                }
            }
        }


        public static double ConvertMasterToMeter(double num)
        {
            return num * m_defaultUnitsToMeters;
        }
        public static double ConvertMeterToMaster(double num)
        {
            return num / m_defaultUnitsToMeters;
        }
        public static string FormatNumber(double num)
        {
            return FormatForDisplay.Double(num);
        }
    }
}